home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Experimental BBS Explossion 3
/
Experimental BBS Explossion III.iso
/
c
/
pcw.zip
/
CDIR.C
< prev
next >
Wrap
Text File
|
1990-01-30
|
15KB
|
375 lines
/**********************************************************/
/* Program Id. Cdir.C. */
/* Author. Stan Milam. */
/* Installation. Mountain View College */
/* Date Written. 09/06/87. */
/* Compiler. Turbo C V1.00, */
/* Microsoft C V5.00, */
/* Mix Power C V1.00. */
/* Comments: This program was written to demonstrate the */
/* use of software interrupts, both DOS & BIOS. The */
/* functions performed are to get a directory listing by */
/* making DOS interrupt calls and to display the directory*/
/* on the screen with a window managed by ROM BIOS. Also */
/* the bit masking & shifting capabilities of C are */
/* demonstrated. */
/* WARNING! Do not try to redirect the output to the */
/* printer since some of the line feeds will be performed */
/* by ROM BIOS. */
/**********************************************************/
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <pcwproto.h>
#define TRUE 1
#define FALSE 0
int pause = FALSE; /* A flag to signal pause */
struct dta_type { /* Defines Disk Transfer Area */
char reserved[21]; /* Reserved by DOS */
char fattrib; /* File attribute */
/************************************/
/* The next 3 fields are bit fields */
/************************************/
unsigned int fsec:5; /* Second file was created */
unsigned int fmin:6; /* Minute file was created */
unsigned int fhour:5; /* Hour file was created */
unsigned int fdate; /* Date the file was created */
long fsize; /* Size of the file in bytes */
char fname[13]; /* File name */
};
/***********************************************************/
/* SET_DTA */
/* This function (procedure) will establish a new Disk */
/* Transfer Area. The new DTA will be a structure that */
/* will mirror the information DOS will return to us when */
/* we call the firstfile and nextfile functions. */
/***********************************************************/
void set_dta(dta)
struct dta_type *dta; {
struct SREGS sregs;
union REGS regs;
segread(&sregs); /* Get segment registers' values */
regs.x.ax = 0x1A00; /* DOS function Set Disk Transfer Area */
regs.x.dx = (unsigned int) dta; /* Address of our DTA */
int86x(0x21,®s,®s,&sregs); /* Call DOS to set up new DTA */
}
/***********************************************************/
/* INITIALIZE */
/* This function will initialize the program. Mainly it */
/* will clear the screen, print some headings and invoke */
/* the function to set up a new DTA for the program. */
/***********************************************************/
void initialize(dta)
struct dta_type *dta; { /* Pointer to DTA */
vcls(); /* Clear the screen */
set_dta(dta); /* Establish Disk Transfer Area */
printf("\n\n\n");
printf(" File Name Size Date Time Attribute\n");
printf(" ------------ ------ -------- -------- -------------\n");
}
/**********************************************************/
/* FIRSTFILE */
/* This function will find the first file that matches */
/* search argument. First a call is made to DOS to set */
/* up a Disk Transfer Area in a structure dta. Next the */
/* call is made to find the first file. When the file is*/
/* found DOS will pass information about the file back to*/
/* us in the Disk Transfer area that we set up. */
/**********************************************************/
int firstfile(s_arg)
char *s_arg; { /* Pointer to the search argument */
union REGS regs;
struct SREGS sregs;
segread(&sregs); /* Get segment registers */
regs.x.ax = 0x4e00; /* DOS function Find First File */
regs.x.dx = (unsigned int) s_arg; /* Offset of search argument */
regs.x.cx = 0x003f; /* File Attribute = ALL */
int86x(0x21,®s,®s,&sregs); /* Call DOS to find first file */
if (regs.x.ax == 0) /* if no error occured then */
return(TRUE); /* return a true condition */
else
return(FALSE); /* otherwise .... */
}
/***********************************************************/
/* NEXTFILE */
/* This function is much like the last except it gets the */
/* next file which matchs our search argument. It passes */
/* back a flag = FALSE when no more files are found */
/***********************************************************/
int nextfile(void) {
union REGS regs;
regs.x.ax = 0x4f00; /* DOS function for nextfile */
int86(0x21,®s,®s); /* Call DOS */
if (regs.x.ax == 0) /* Check for an error or no more */
return(TRUE); /* files. */
else
return(FALSE);
}
/***********************************************************/
/* PFILE */
/* This function will print all the pertinate information */
/* about the file retrieved such as its name, time & date */
/* created, and its attribute (read-only, hidden, system */
/* etc...). */
/***********************************************************/
void pfile(dta,fcount)
struct dta_type *dta;
int fcount; {
int hour,min,sec,year,day,month; /* variables to get from dta */
char attribute[16]; /* pointer to attribute description */
long size; /* size of file */
int dattr; /* debug only */
char *pr1, *pr2; /* print strings */
char name[9], extention[4]; /* File Name & Extention */
char *wrk;
pr1 = " %-8s %-3s %6ld %02d/%02d/%02d %02d:%02d:%02d %s\n";
pr2 = " %-8s %-3s %6ld %02d/%02d/%02d %02d:%02d:%02d %s";
attribute[0] = '\0';
size = dta->fsize;
hour = dta->fhour; /* Hour from bit field */
min = dta->fmin; /* Minute from bit field */
sec = dta->fsec * 2; /* Seconds * 2 from bit field */
year = (dta->fdate & 0xfe00) >> 9; /* mask & shift to get year */
month =(dta->fdate & 0x01e0) >> 5; /* mask & shift to get month */
day = (dta->fdate & 0x001f); /* just mask to get day */
year += 80; /* year + 1980 */
if ((wrk = strchr(dta->fname,'.')) == NULL) { /* Find Extention */
strcpy(name, dta->fname);
strcpy(extention, " ");
}
else {
if (strcmp(dta->fname, wrk) != 0) { /* Is it ".." or "." */
*wrk = '\0'; /* No - delimit name & ext */
strcpy(name, dta->fname); /* Copy file name */
strcpy(extention, ++wrk); /* Copy extention */
}
else {
strcpy(name, dta->fname); /* Copy ".." or "." */
strcpy(extention, " "); /* Put spaces into ext. */
}
}
if ((dta -> fattrib & 0x01) == 0x01)
strcat(attribute,"R "); /* Read Only */
else
strcat(attribute,". ");
if ((dta -> fattrib & 0x02) == 0x02)
strcat(attribute,"H "); /* Hidden */
else
strcat(attribute,". ");
if ((dta -> fattrib & 0x04) == 0x04)
strcat(attribute,"S "); /* System */
else
strcat(attribute,". ");
if ((dta -> fattrib & 0x08) == 0x08)
strcat(attribute,"V "); /* Volume Label */
else
strcat(attribute,". ");
if ((dta -> fattrib & 0x10) == 0x10)
strcat(attribute,"D "); /* Directory */
else
strcat(attribute,". ");
if ((dta -> fattrib & 0x20) == 0x20)
strcat(attribute,"Arc"); /* Archive */
else
strcat(attribute,"...");
if (fcount % 12 == 0 && pause){ /* If pause then stop */
while(!kbhit()); /* and wait for a key */
getch();
}
if (fcount >= 13) {
printf(pr2,
name,extention,size,month,day,year,hour,min,sec,attribute);
scroll(6,2,18,79,7,0,-1);
set_cursor_pos(18,1);
}
else
printf(pr1,
name,extention,size,month,day,year,hour,min,sec,attribute);
}
/**********************************************************/
/* FREE_SPACE */
/* This function will print the total number of files */
/* listed along with the total disk space, total disk */
/* space used, total disk space available, and percent of */
/* free disk space. We are going to use the DOS function */
/* Get Free Disk Space (Int 0x21 function 0x36) to do all */
/* of this fancy stuff. Upon return from the DOS call */
/* the registers will reflect the following: */
/* AX = sectors per cluster. */
/* BX = number of available clusters. */
/* CX = bytes per sector. */
/* DX = total number of clusters. */
/**********************************************************/
void free_space(fcount,drive)
int fcount; int drive; {
union REGS regs; /* Set up registers of course */
unsigned long total,avail,used; /* Need longs for big numbers */
int percent; /* Nuff said? */
regs.x.ax = 0x3600; /* DOS function Free Space */
regs.x.dx = drive; /* Set for specified drive */
int86(0x21,®s,®s); /* Call DOS */
if (regs.x.ax == 0xffff) { /* If an error then print a */
puts("*** Invalid Drive Specification ***"); /* nasty message */
exit(16); /* and return home */
}
total = (long) regs.x.dx * regs.x.cx * regs.x.ax; /* Total bytes on disk */
avail = (long) regs.x.ax * regs.x.bx * regs.x.cx; /* Available bytes */
used = total - avail; /* Total used */
percent = (avail * 100) / total; /* % of free space */
puts(" ");
printf(" %3d file(s) %8ld total disk space\n",fcount, total);
printf(" %8ld total disk space available\n",avail);
printf(" %8ld total disk space used\n",used);
printf(" %8d percent free disk space\n",percent);
}
/**********************************************************/
/* PARSER */
/* This function will parse the command line for a drive */
/* specification. If it is present then the drive spec */
/* will be used when we call free_space so that we use the*/
/* correct disk drive. Default drive = 0, A drive = 1, */
/* B drive = 2, etc.... */
/* Changed code to append "*.*" if no file spec was */
/* entered. Example: */
/* cdir a: will turn into cdir a:*.* */
/* cdir \dos\ will turn into cdir \dos\*.* */
/**********************************************************/
int parser(arg)
char arg[]; {
int retval = 0; /* Assume Defualt Drive */
char *wrk; /* Character Work Pointer */
if (arg[1] == ':') { /* If second char is ':' then return */
retval = toupper(arg[0]) - 64; /* Covert to numeric */
if (arg[2] == '\0') /* Char after ':' a null? */
strcat(arg, "*.*"); /* Yes! - concatenate wildcard */
}
if ((wrk = strrchr(arg, '\\')) != NULL) {
if (*(wrk + 1) == NULL) {
strcat(arg, "*.*");
}
}
return(retval);
}
/***********************************************************/
/* PARSE_COMMAND */
/* */
/* This function does two things: Takes all command line */
/* arguments and converts the alpha characters to upper */
/* case. Secondly, it searches the arguments for "/P" and */
/* returns TRUE indicating that the user wants to pause */
/* after one full page of output. */
/***********************************************************/
int parse_command(argc, argv)
int argc;
char *argv [];
{
int i;
char *wrk;
for (i = 1; i < argc; i++) { /* Change all alpha chars */
wrk = argv[i]; /* In command line args to*/
while(*wrk) { /* Upper Case */
*wrk = toupper(*wrk);
wrk++;
}
}
for (i = 1; i < argc; i++) { /* Now search for the */
wrk = argv[i]; /* "/P" in one of the */
if (strcmp(wrk, "/P") == 0) /* Arguments */
return(TRUE);
}
return(FALSE);
}
/******************************/
/* MAIN */
/******************************/
int main(argc,argv)
int argc;
char *argv[]; {
struct dta_type dta;
int fcount = 0, drive =0;
char *arg;
set_int24();
pause = parse_command(argc, argv);
if (pause && argc > 2) {
arg = argv[1];
drive = parser(arg);
}
else
if (pause && argc > 1)
arg = "*.*";
else
if (argc > 1) {
arg = argv[1];
drive = parser(arg);
}
else
arg = "*.*";
initialize(&dta); /* Initialize the program */
if (firstfile(arg)) { /* Is there a first file? */
do {
fcount += 1; /* Yes - print file name until */
pfile(&dta,fcount); /* no more matches */
}
while (nextfile());
free_space(fcount,drive); /* And then print info about */
} /* the disk */
else {
puts("*** No matching files ***");
free_space(fcount,drive);
return(16);
}
return (0);
}